namespace DotNetNuke.UI
{
    using DotNetNuke.Common;
    using DotNetNuke.Entities.Modules.Actions;
    using DotNetNuke.Entities.Portals;
    using DotNetNuke.Entities.Tabs;
    using DotNetNuke.Entities.Users;
    using DotNetNuke.Security;
    using DotNetNuke.UI.Containers;
    using DotNetNuke.UI.WebControls;
    using Microsoft.VisualBasic;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Collections;
    using System.Web;
    using System.Web.UI;

    public class Navigation
    {
        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Recursive function to add module's actions to the DNNNodeCollection based off of passed in ModuleActions
        /// </summary>
        /// <param name="objParentAction">Parent action</param>
        /// <param name="objParentNode">Parent node</param>
        /// <param name="objModule">Module to base actions off of</param>
        /// <param name="objUserInfo">User Info Object</param>
        /// <remarks>
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private static void AddChildActions(ModuleAction objParentAction, DNNNode objParentNode, ActionBase objModule, UserInfo objUserInfo, Control objControl)
        {
            IEnumerator refObjectHelperL0=null;
            try
            {
                refObjectHelperL0 = objParentAction.Actions.GetEnumerator();
                while (refObjectHelperL0.MoveNext())
                {
                    ModuleAction objAction = (ModuleAction) refObjectHelperL0.Current;
                    if (objAction.Title == "~")
                    {
                        objParentNode.DNNNodes.AddBreak();
                    }
                    else if (objAction.Visible & PortalSecurity.HasNecessaryPermission(objAction.Secure, (PortalSettings) HttpContext.Current.Items["PortalSettings"], objModule.ModuleConfiguration, objUserInfo.UserID.ToString()))
                    {
                        if ((!objModule.EditMode || objModule.PortalSettings.ActiveTab.IsAdminTab) || DotNetNuke.Common.Globals.IsAdminControl())
                        {
                        }
                        if ((((objAction.Secure != SecurityAccessLevel.Anonymous) && (objAction.Secure != SecurityAccessLevel.View)) ? 1 : 0) != 0)
                        {
                            int i = objParentNode.DNNNodes.Add();
                            DNNNode objNode = objParentNode.DNNNodes[i];
                            objNode.ID = objAction.ID.ToString();
                            objNode.Key = objAction.ID.ToString();
                            objNode.Text = objAction.Title;
                            if (Strings.Len(objAction.ClientScript) > 0)
                            {
                                objNode.JSFunction = objAction.ClientScript;
                                objNode.ClickAction = eClickAction.None;
                            }
                            else if (Strings.Len(objAction.Url) > 0)
                            {
                                objNode.NavigateURL = objAction.Url;
                                objNode.ClickAction = eClickAction.Navigate;
                            }
                            else
                            {
                                objNode.ClickAction = eClickAction.PostBack;
                            }
                            objNode.Image = objAction.Icon;
                            if (objAction.HasChildren())
                            {
                                AddChildActions(objAction, objNode, objModule, objUserInfo, objControl);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (refObjectHelperL0 is IDisposable)
                {
                    (refObjectHelperL0 as IDisposable).Dispose();
                }
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Assigns common properties from passed in tab to newly created DNNNode that is added to the passed in DNNNodeCollection
        /// </summary>
        /// <param name="objTab">Tab to base DNNNode off of</param>
        /// <param name="objNodes">Node collection to append new node to</param>
        /// <param name="objBreadCrumbs">Hashtable of breadcrumb IDs to efficiently determine node's BreadCrumb property</param>
        /// <param name="objPortalSettings">Portal settings object to determine if node is selected</param>
        /// <remarks>
        /// Logic moved to separate sub to make GetNavigationNodes cleaner
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private static void AddNode(DotNetNuke.Entities.Tabs.TabInfo objTab, DNNNodeCollection objNodes, Hashtable objBreadCrumbs, PortalSettings objPortalSettings, ToolTipSource eToolTips)
        {
            DNNNode objNode = new DNNNode();
            if (objTab.Title == "~")
            {
                objNodes.AddBreak();
            }
            else
            {
                if (objBreadCrumbs.Contains(objTab.TabID))
                {
                    objNode.BreadCrumb = true;
                    if (objTab.TabID == objPortalSettings.ActiveTab.TabID)
                    {
                        objNode.Selected = true;
                    }
                }
                if (objTab.DisableLink)
                {
                    objNode.Enabled = false;
                }
                objNode.ID = objTab.TabID.ToString();
                objNode.Key = objNode.ID;
                objNode.Text = objTab.TabName;
                objNode.NavigateURL = objTab.FullUrl;
                objNode.ClickAction = eClickAction.Navigate;
                if (objTab.IsAdminTab)
                {
                    if (objTab.IconFile != "")
                    {
                        objNode.Image = DotNetNuke.Common.Globals.ApplicationPath + "/images/" + objTab.IconFile;
                    }
                }
                else if (objTab.IconFile != "")
                {
                    objNode.Image = objTab.IconFile;
                }
                switch (((int) eToolTips))
                {
                    case 0:
                        objNode.ToolTip = objTab.TabName;
                        break;

                    case 1:
                        objNode.ToolTip = objTab.Title;
                        break;

                    case 2:
                        objNode.ToolTip = objTab.Description;
                        break;
                }
                objNodes.Add(objNode);
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// This function provides a central location to obtain a generic node collection of the actions associated 
        /// to a module based off of the current user's context
        /// </summary>
        /// <param name="objActionRoot">Root module action</param>
        /// <param name="objModule">Module whose actions you wish to obtain</param>
        /// <returns></returns>
        /// <remarks>
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public static DNNNodeCollection GetActionNodes(ModuleAction objActionRoot, ActionBase objModule, Control objControl)
        {
            DNNNodeCollection objCol = new DNNNodeCollection(objModule.ClientID);
            if (objActionRoot.Visible)
            {
                objCol.Add();
                DNNNode objRoot = objCol[0];
                objRoot.ID = objActionRoot.ID.ToString();
                objRoot.Key = objActionRoot.ID.ToString();
                objRoot.Text = objActionRoot.Title;
                objRoot.NavigateURL = objActionRoot.Url;
                objRoot.Image = objActionRoot.Icon;
                AddChildActions(objActionRoot, objRoot, objModule, UserController.GetCurrentUserInfo(), objControl);
            }
            return objCol;
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Allows for DNNNode object to be easily obtained based off of passed in ID
        /// </summary>
        /// <param name="strID">NodeID to retrieve</param>
        /// <param name="strNamespace">Namespace for node collection (usually control's ClientID)</param>
        /// <returns>DNNNode</returns>
        /// <remarks>
        /// Primary purpose of this is to obtain the DNNNode needed for the events exposed by the NavigationProvider
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public static DNNNode GetNavigationNode(string strID, string strNamespace)
        {
            DNNNode objNode = GetNavigationNodes(strNamespace).FindNode(strID);
            DNNNodeCollection objReturnNodes = new DNNNodeCollection(strNamespace);
            objReturnNodes.Import(objNode);
            objReturnNodes[0].ID = strID;
            return objReturnNodes[0];
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// This function provides a central location to obtain a generic node collection of the pages/tabs included in
        /// the current context's (user) navigation hierarchy
        /// </summary>
        /// <param name="strNamespace">Namespace (typically control's ClientID) of node collection to create</param>
        /// <returns>Collection of DNNNodes</returns>
        /// <remarks>
        /// Returns all navigation nodes for a given user 
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public static DNNNodeCollection GetNavigationNodes(string strNamespace)
        {
            return GetNavigationNodes(strNamespace, ToolTipSource.None, -1, -1, 0);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// This function provides a central location to obtain a generic node collection of the pages/tabs included in
        /// the current context's (user) navigation hierarchy
        /// </summary>
        /// <param name="objRootNode">Node in which to add children to</param>
        /// <param name="eToolTips">Enumerator to determine what text to display in the tooltips</param>
        /// <param name="intStartTabId">If using Populate On Demand, then this is the tab id of the root element to retrieve (-1 for no POD)</param>
        /// <param name="intDepth">If Populate On Demand is enabled, then this parameter determines the number of nodes to retrieve beneath the starting tab passed in (intStartTabId) (-1 for no POD)</param>
        /// <param name="intNavNodeOptions">Bitwise integer containing values to determine what nodes to display (self, siblings, parent)</param>
        /// <returns>Collection of DNNNodes</returns>
        /// <remarks>
        /// Returns a subset of navigation nodes based off of passed in starting node id and depth
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public static DNNNodeCollection GetNavigationNodes(DNNNode objRootNode, ToolTipSource eToolTips, int intStartTabId, int intDepth, int intNavNodeOptions)
        {
            int i=0;
            int intLastBreadCrumbId=0;
            DotNetNuke.Entities.Tabs.TabInfo objTab;
            PortalSettings objPortalSettings = PortalController.GetCurrentPortalSettings();
            bool blnAdminMode = PortalSecurity.IsInRoles(objPortalSettings.AdministratorRoleName) | PortalSecurity.IsInRoles(objPortalSettings.ActiveTab.AdministratorRoles.ToString());
            bool blnFoundStart = intStartTabId == -1;
            Hashtable objBreadCrumbs = new Hashtable();
            Hashtable objTabLookup = new Hashtable();
            DNNNodeCollection objRootNodes = objRootNode.DNNNodes;
            int refIntHelperL0 = objPortalSettings.ActiveTab.BreadCrumbs.Count - 1;
            for (i = 0; i <= refIntHelperL0; i++)
            {
                objBreadCrumbs.Add(((DotNetNuke.Entities.Tabs.TabInfo) objPortalSettings.ActiveTab.BreadCrumbs[i]).TabID, 1);
                intLastBreadCrumbId = ((DotNetNuke.Entities.Tabs.TabInfo) objPortalSettings.ActiveTab.BreadCrumbs[i]).TabID;
            }
            int refIntHelperL1 = objPortalSettings.DesktopTabs.Count - 1;
            for (i = 0; i <= refIntHelperL1; i++)
            {
                objTab = (DotNetNuke.Entities.Tabs.TabInfo) objPortalSettings.DesktopTabs[i];
                objTabLookup.Add(objTab.TabID, objTab);
            }
            int refIntHelperL2 = objPortalSettings.DesktopTabs.Count - 1;
            for (i = 0; i <= refIntHelperL2; i++)
            {
                try
                {
                    objTab = (DotNetNuke.Entities.Tabs.TabInfo) objPortalSettings.DesktopTabs[i];
                    if (IsTabShown(objTab, blnAdminMode))
                    {
                        DNNNode objParentNode = objRootNodes.FindNode(objTab.ParentId.ToString());
                        bool blnParentFound = objParentNode != null;
                        if (objParentNode == null)
                        {
                            objParentNode = objRootNode;
                        }
                        DNNNodeCollection objParentNodes = objParentNode.DNNNodes;
                        if (objTab.TabID == intStartTabId)
                        {
                            if (((intNavNodeOptions & 2) != 0) && (objTabLookup[objTab.ParentId] != null))
                            {
                                AddNode((DotNetNuke.Entities.Tabs.TabInfo) objTabLookup[objTab.ParentId], objParentNodes, objBreadCrumbs, objPortalSettings, eToolTips);
                                objParentNodes = objRootNodes.FindNode(objTab.ParentId.ToString()).DNNNodes;
                            }
                            if ((intNavNodeOptions & 1) != 0)
                            {
                                AddNode(objTab, objParentNodes, objBreadCrumbs, objPortalSettings, eToolTips);
                            }
                        }
                        else if (((((intNavNodeOptions & 4) != 0) && IsTabSibling(objTab, intStartTabId, objTabLookup)) ? 1 : 0) != 0)
                        {
                            AddNode(objTab, objParentNodes, objBreadCrumbs, objPortalSettings, eToolTips);
                        }
                        else if (blnParentFound)
                        {
                            if (((((intNavNodeOptions & 4) != 0) || !IsTabSibling(objTab, intStartTabId, objTabLookup)) ? 1 : 0) != 0)
                            {
                                bool blnPOD = (intNavNodeOptions & 8) != 0;
                                if (IsTabPending(objTab, objParentNode, objRootNode, intDepth, objBreadCrumbs, intLastBreadCrumbId, blnPOD))
                                {
                                    if (blnPOD)
                                    {
                                        objParentNode.HasNodes = true;
                                    }
                                }
                                else
                                {
                                    AddNode(objTab, objParentNodes, objBreadCrumbs, objPortalSettings, eToolTips);
                                }
                            }
                        }
                        else if (((((intNavNodeOptions & 1) == 0) && (objTab.ParentId == intStartTabId)) ? 1 : 0) != 0)
                        {
                            AddNode(objTab, objParentNodes, objBreadCrumbs, objPortalSettings, eToolTips);
                        }
                    }
                }
                catch (Exception exception1)
                {
                    
                    Exception ex = exception1;
                    throw ex;
                    
                }
            }
            return objRootNodes;
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// This function provides a central location to obtain a generic node collection of the pages/tabs included in
        /// the current context's (user) navigation hierarchy
        /// </summary>
        /// <param name="strNamespace">Namespace (typically control's ClientID) of node collection to create</param>
        /// <param name="eToolTips">Enumerator to determine what text to display in the tooltips</param>
        /// <param name="intStartTabId">If using Populate On Demand, then this is the tab id of the root element to retrieve (-1 for no POD)</param>
        /// <param name="intDepth">If Populate On Demand is enabled, then this parameter determines the number of nodes to retrieve beneath the starting tab passed in (intStartTabId) (-1 for no POD)</param>
        /// <param name="intNavNodeOptions">Bitwise integer containing values to determine what nodes to display (self, siblings, parent)</param>
        /// <returns>Collection of DNNNodes</returns>
        /// <remarks>
        /// Returns a subset of navigation nodes based off of passed in starting node id and depth
        /// </remarks>
        /// <history>
        /// [Jon Henning]	8/9/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public static DNNNodeCollection GetNavigationNodes(string strNamespace, ToolTipSource eToolTips, int intStartTabId, int intDepth, int intNavNodeOptions)
        {
            DNNNodeCollection objCol = new DNNNodeCollection(strNamespace);
            return GetNavigationNodes(new DNNNode(objCol.XMLNode), eToolTips, intStartTabId, intDepth, intNavNodeOptions);
        }

        private static bool IsTabPending(DotNetNuke.Entities.Tabs.TabInfo objTab, DNNNode objParentNode, DNNNode objRootNode, int intDepth, Hashtable objBreadCrumbs, int intLastBreadCrumbId, bool blnPOD)
        {
            if (intDepth == -1)
            {
                return false;
            }
            if (((objParentNode.Level + 1) - objRootNode.Level) <= intDepth)
            {
                return false;
            }
            if (blnPOD)
            {
                if (objBreadCrumbs.Contains(objTab.TabID))
                {
                    return false;
                }
                if (((objBreadCrumbs.Contains(objTab.ParentId) && (intLastBreadCrumbId != objTab.ParentId)) ? 1 : 0) != 0)
                {
                    return false;
                }
            }
            return true;
        }

        private static bool IsTabShown(DotNetNuke.Entities.Tabs.TabInfo objTab, bool blnAdminMode)
        {
            if (((objTab.IsVisible && !objTab.IsDeleted) && ((DateTime.Compare(objTab.StartDate, DateAndTime.Now) >= 0) || (DateTime.Compare(objTab.EndDate, DateAndTime.Now) <= 0))) && !blnAdminMode)
            {
            }
            return ((PortalSecurity.IsInRoles(objTab.AuthorizedRoles) ? 1 : 0) != 0);
        }

        private static bool IsTabSibling(DotNetNuke.Entities.Tabs.TabInfo objTab, int intStartTabId, Hashtable objTabLookup)
        {
            if (intStartTabId == -1)
            {
                return (objTab.ParentId == -1);
            }
            return (objTab.ParentId == ((DotNetNuke.Entities.Tabs.TabInfo) objTabLookup[intStartTabId]).ParentId);
        }

        public enum NavNodeOptions
        {
            IncludeParent = 2,
            IncludeSelf = 1,
            IncludeSiblings = 4,
            MarkPendingNodes = 8
        }

        public enum ToolTipSource
        {
            TabName,
            Title,
            Description,
            None
        }
    }
}

